package it.unisa.ingegneria.tdp.esercitazione5;
import java.util.ArrayList;
import java.util.Iterator;

/**
 * 
 * Classe per la gestione dei grafi
 */
public class Graph<T> implements GraphInterface<T> {

	private ArrayList<MyVertex<T>> vertexes;
	private ArrayList<MyEdge<T>> edges;
	
	
	public Graph() {
		
		this.vertexes =new ArrayList<MyVertex<T>>();
		this.edges =new ArrayList<MyEdge<T>>();
		
	}
	
	@Override
	public Iterable <MyVertex<T>> vertices() {
		return vertexes;
	}
	
	/* Metodo utilizzato per i test*/
	public String TestVertices(){
		String s = "";
		Iterator<MyVertex<T>> i = this.vertexes.iterator();
		while(i.hasNext())
			s += i.next().toString();
		
		return s;
	}
	
	public ArrayList<MyVertex<T>> getVertici() {
		return vertexes;
	}

	public void setVertici(ArrayList<MyVertex<T>> vertici) {
		this.vertexes = vertici;
	}
	
	public ArrayList<MyEdge<T>> getArchi() {
		return edges;
	}
	
	public void setArchi(ArrayList<MyEdge<T>> archi) {
		this.edges = archi;
	}

	@Override
	public Iterable<MyEdge<T>> edges() {
		return edges;
	}

	@Override
	public MyVertex<T> insertVertex(T e) {
		MyVertex<T> nuovo = new MyVertex<T>(e);
		vertexes.add(nuovo);
		return nuovo;
	}

	@Override
	public MyEdge<T> insertEdge(MyVertex<T> s, MyVertex<T> d, int weight) {
		MyEdge<T> nuovo=new MyEdge<T>(s, d);
		s.addOutEdge(nuovo);
		edges.add(nuovo);
		nuovo.setDecorator("weight", weight); 
		return nuovo;
	} 
	
	/* Metodo utilizzato per i test*/
	public MyEdge<T> insertEdge(MyVertex<T> s, MyVertex<T> d) {
		MyEdge<T> nuovo=new MyEdge<T>(s, d);
		s.addOutEdge(nuovo);
		edges.add(nuovo); 
		return nuovo;
	} 

	@Override
	public Iterable<MyEdge<T>> outgoingEdges(MyVertex<T> v) {
		return v.getOutgoigEdges();
	}
	
	/* Metodo utilizzato per i test*/
	public String testOutgoingEdges(MyVertex<T> v){
		String s = "";
		Iterator<MyVertex<T>> i = v.outgoingVertexes().iterator();
		while(i.hasNext())
			s += i.next().toString();
		
		return s;
	}

	@Override
	public int numEdges() {
		return edges.size();
	}

	@Override
	public int numVertices() {
		return vertexes.size();
	}

	public String toString()
	{
		String stampa="";
		
		Iterator<MyVertex<T>> v = this.vertexes.iterator();
		Iterator<MyVertex<T>> a;
		MyVertex<T> verticeTemp;
		
		while(v.hasNext())
		{
			verticeTemp=v.next();
			a=verticeTemp.outgoingVertexes().iterator();
			stampa=stampa+verticeTemp.toString()+" -- ";
			while(a.hasNext())
			{
				verticeTemp=a.next();
				stampa=stampa+verticeTemp.toString()+" -- ";
			}
			stampa=stampa+"\n";
		}
		
		return stampa;
	}
	
	/* Metodo utilizzato per i test*/
	public String stampaTest(){
		String stampa="";
		
		Iterator<MyVertex<T>> v = this.vertexes.iterator();
		Iterator<MyVertex<T>> a;
		MyVertex<T> verticeTemp;
		
		while(v.hasNext())
		{
			verticeTemp=v.next();
			a=verticeTemp.outgoingVertexes().iterator();
			stampa=stampa+verticeTemp.toString();
			while(a.hasNext())
			{
				verticeTemp=a.next();
				stampa=stampa+verticeTemp.toString();
			}
			
		}
		
		return stampa;
	}
	
}
